home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 97 / CD-ROM 97 / CD-ROM 97.iso / internet / ghostzilla / ghsetup.exe / chrome / comm.jar / content / editor / publishprefs.js < prev    next >
Encoding:
JavaScript  |  2002-04-09  |  25.5 KB  |  913 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Netscape Public License
  6.  * Version 1.1 (the "License"); you may not use this file except in
  7.  * compliance with the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/NPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is mozilla.org code.
  16.  *
  17.  * The Initial Developer of the Original Code is 
  18.  * Netscape Communications Corporation.
  19.  * Portions created by the Initial Developer are Copyright (C) 2001
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *  cmanske@netscape.com
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the NPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the NPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39.  
  40. /****************** Get publishing data methods *******************/
  41.  
  42. // Build an array of all publish site data obtained from prefs
  43. function GetPublishSiteData()
  44. {
  45.   var publishBranch = GetPublishPrefsBranch();
  46.   if (!publishBranch)
  47.     return null;
  48.  
  49.   // Array of site names - sorted, but don't put default name first
  50.   var siteNameList = GetSiteNameList(true, false);
  51.   if (!siteNameList)
  52.     return null;
  53.  
  54.   // Array of all site data
  55.   var siteArray = [];
  56.  
  57.   var siteCount = siteNameList.length;
  58.  
  59.   // Build array for sites in alphabetical order (XXX Ascii sort, not locale-aware)
  60.   if (siteCount > 1)
  61.     siteNameList.sort();
  62.  
  63.   // We  rewrite siteName prefs to eliminate names if data is bad
  64.   //  and to be sure order is the same as sorted name list
  65.   try {
  66.     publishBranch.deleteBranch("site_name.");
  67.   } catch (e) {}
  68.  
  69.   // Get publish data using siteName as the key
  70.   var index = 0;
  71.   for (var i = 0; i < siteCount; i++)
  72.   {
  73.     // Associated data uses site name as key
  74.     var publishData = GetPublishData_internal(publishBranch, siteNameList[i]);
  75.     if (publishData)
  76.     {
  77.       siteArray[index] = publishData;
  78.       SetPublishStringPref(publishBranch, "site_name."+index, siteNameList[i]);
  79.       index++;
  80.     }
  81.     else
  82.     {
  83.       try {
  84.         // Remove bad site prefs now
  85.         publishBranch.deleteBranch("site_data." + siteNameList[i] + ".");
  86.       } catch (e) {}
  87.     }
  88.   }
  89.  
  90.   SavePrefFile();
  91.  
  92.   if (index == 0) // No Valid pref records found!
  93.     return null;
  94.  
  95.  
  96.   return siteArray;
  97. }
  98.  
  99. function GetDefaultPublishSiteName()
  100. {
  101.   var publishBranch = GetPublishPrefsBranch();
  102.   var name = "";  
  103.   if (publishBranch)
  104.     name = GetPublishStringPref(publishBranch, "default_site");
  105.  
  106.   return name;
  107. }
  108.  
  109. // Return object with all info needed to publish
  110. //   from database of sites previously published to.
  111. function CreatePublishDataFromUrl(docUrl)
  112. {
  113.   if (!docUrl || IsUrlAboutBlank(docUrl) || GetScheme(docUrl) == "file")
  114.     return null;
  115.  
  116.   var pubSiteData = GetPublishSiteData();
  117.   if (pubSiteData)
  118.   {
  119.     var dirObj = {};
  120.     var index = FindSiteIndexAndDocDir(pubSiteData, docUrl, dirObj);
  121.     var publishData;
  122.     if (index != -1)
  123.     {
  124.       publishData = pubSiteData[index];
  125.       publishData.docDir = FormatDirForPublishing(dirObj.value)
  126.  
  127.       //XXX Problem: OtherDir: How do we decide when to use the dir in 
  128.       //    publishSiteData (default DocDir) or docDir from current filepath?
  129.       publishData.otherDir = FormatDirForPublishing(pubSiteData[index].otherDir);
  130.  
  131.       publishData.filename = GetFilename(docUrl);
  132.       publishData.notInSiteData = false;
  133.       return publishData;
  134.     }
  135.   }
  136.  
  137.   // Document wasn't found in publish site database
  138.   // Create data just from URL
  139.  
  140.   // Extract username and password from docUrl
  141.   var userObj = {};
  142.   var passObj = {};
  143.   var pubUrl = StripUsernamePassword(docUrl, userObj, passObj);
  144.  
  145.   // Strip off filename
  146.   var lastSlash = pubUrl.lastIndexOf("\/");
  147.   //XXX Look for "?", "=", and "&" ?
  148.   pubUrl = pubUrl.slice(0, lastSlash+1);
  149.  
  150.   publishData = { 
  151.     siteName : pubUrl,
  152.     filename : GetFilename(docUrl),
  153.     username : userObj.value,
  154.     password : passObj.value,
  155.     savePassword : false,
  156.     publishUrl : pubUrl,
  157.     browseUrl  : pubUrl,
  158.     docDir     : "",
  159.     otherDir   : "",
  160.     publishOtherFiles : true,
  161.     dirList    : [""],
  162.     saveDirs   : false,
  163.     notInSiteData : true
  164.   }
  165.  
  166.   return publishData;
  167. }
  168.  
  169. // Similar to above, but in param is a site profile name
  170. // Note that this is more efficient than getting from a URL,
  171. //   since we don't have to get all the sitedata but can key off of sitename.
  172. // Caller must supply the current docUrl or just a filename
  173. // If doc URL is supplied, we find the publish subdirectory if publishUrl is part of docUrl
  174. function GetPublishDataFromSiteName(siteName, docUrlOrFilename)
  175. {
  176.   var publishBranch = GetPublishPrefsBranch();
  177.   if (!publishBranch)
  178.     return null;
  179.  
  180.   var siteNameList = GetSiteNameList(false, false);
  181.   if (!siteNameList)
  182.     return null;
  183.   for (var i = 0; i < siteNameList.length; i++)
  184.   {
  185.     if (siteNameList[i] == siteName)
  186.     {
  187.       var publishData = GetPublishData_internal(publishBranch, siteName);
  188.       if (GetScheme(docUrlOrFilename))
  189.         FillInMatchingPublishData(publishData, docUrlOrFilename);
  190.       else
  191.         publishData.filename = docUrlOrFilename;
  192.  
  193.       return publishData;
  194.     }
  195.   }
  196.   return null;
  197. }
  198.  
  199. function GetDefaultPublishData()
  200. {
  201.   var publishBranch = GetPublishPrefsBranch();
  202.   if (!publishBranch)
  203.     return null;
  204.  
  205.   var siteName = GetPublishStringPref(publishBranch, "default_site");
  206.   if (!siteName)
  207.     return null;
  208.  
  209.   return GetPublishData_internal(publishBranch, siteName);
  210. }
  211.  
  212. function GetPublishData_internal(publishBranch, siteName)
  213. {
  214.   if (!publishBranch || !siteName)
  215.     return null;
  216.  
  217.   var prefPrefix = "site_data." + siteName + ".";
  218.  
  219.   // We must have a publish url, else we ignore this site
  220.   // (siteData and siteNames for sites with incomplete data 
  221.   //  will get deleted by SavePublishSiteDataToPrefs)
  222.   var publishUrl = GetPublishStringPref(publishBranch, prefPrefix+"url");
  223.   if (!publishUrl)
  224.     return null;
  225.  
  226.   var savePassword = false;
  227.   var publishOtherFiles = true;
  228.   try {
  229.     savePassword = publishBranch.getBoolPref(prefPrefix+"save_password");
  230.     publishOtherFiles = publishBranch.getBoolPref(prefPrefix+"publish_other_files");
  231.   } catch (e) {}
  232.  
  233.   var publishData = { 
  234.     siteName : siteName,
  235.     filename : "",
  236.     username : GetPublishStringPref(publishBranch, prefPrefix+"username"),
  237.     savePassword : savePassword,
  238.     publishUrl : publishUrl,
  239.     browseUrl  : GetPublishStringPref(publishBranch, prefPrefix+"browse_url"),
  240.     docDir     : FormatDirForPublishing(GetPublishStringPref(publishBranch, prefPrefix+"doc_dir")),
  241.     otherDir   : FormatDirForPublishing(GetPublishStringPref(publishBranch, prefPrefix+"other_dir")),
  242.     publishOtherFiles : publishOtherFiles,
  243.     saveDirs : false
  244.   }
  245.  
  246.   // Get password from PasswordManager
  247.   publishData.password = GetSavedPassword(publishData);
  248.  
  249.   // If password was found, user must have checked "Save password"
  250.   //    checkbox in prompt outside of publishing, so override the pref we stored
  251.   if (publishData.password)
  252.   {
  253.     if (!savePassword)
  254.     {
  255.       try {
  256.         publishPrefsBranch.setBoolPref(prefPrefix+"save_password", true);
  257.       } catch (e) {}
  258.     }
  259.     publishData.savePassword = true;
  260.   }
  261.  
  262.   // Build history list of directories 
  263.   // Always supply the root dir 
  264.   publishData.dirList = [""];
  265.  
  266.   // Get the rest from prefs
  267.   var dirCount = {value:0};
  268.   var dirPrefs;
  269.   try {
  270.     dirPrefs = publishBranch.getChildList(prefPrefix+"dir.", dirCount);
  271.   } catch (e) {}
  272.  
  273.   if (dirPrefs && dirCount.value > 0)
  274.   {
  275.     if (dirCount.value > 1)
  276.       dirPrefs.sort();
  277.  
  278.     for (var j = 0; j < dirCount.value; j++)
  279.     {
  280.       var dirName = GetPublishStringPref(publishBranch, dirPrefs[j]);
  281.       if (dirName)
  282.         publishData.dirList[j+1] = dirName;
  283.     }
  284.   }
  285.  
  286.   return publishData;
  287. }
  288.  
  289. /****************** Save publishing data methods *********************/
  290.  
  291. // Save the siteArray containing all current publish site data
  292. function SavePublishSiteDataToPrefs(siteArray, defaultName)
  293. {
  294.   var publishBranch = GetPublishPrefsBranch();
  295.   if (!publishBranch)
  296.     return false;
  297.  
  298.   try {
  299.     if (siteArray)
  300.     {
  301.       var defaultFound = false;
  302.  
  303.       // Clear existing names and data -- rebuild all site prefs
  304.       publishBranch.deleteBranch("site_name.");
  305.       publishBranch.deleteBranch("site_data.");
  306.  
  307.       for (var i = 0; i < siteArray.length; i++)
  308.       {
  309.         SavePublishData_Internal(publishBranch, siteArray[i], i);
  310.         if (!defaultFound)
  311.           defaultFound = defaultName == siteArray[i].siteName;
  312.       }
  313.       // Assure that we have a default name
  314.       if (siteArray.length && !defaultFound)
  315.         defaultName = siteArray[0].siteName;
  316.     }
  317.  
  318.     // Save default site name
  319.     SetPublishStringPref(publishBranch, "default_site", defaultName);
  320.   
  321.     // Force saving to file so next page edited finds these values
  322.     SavePrefFile();
  323.   }
  324.   catch (ex) { return false; }
  325.  
  326.   return true;
  327. }
  328.  
  329. // Update prefs if publish site already exists
  330. //  or add prefs for a new site
  331. function SavePublishDataToPrefs(publishData)
  332. {
  333.   if (!publishData || !publishData.publishUrl)
  334.     return false;
  335.  
  336.   var publishBranch = GetPublishPrefsBranch();
  337.   if (!publishBranch)
  338.     return false;
  339.  
  340.   // Use the site URL if no site name is provided
  341.   if (!publishData.siteName)
  342.     publishData.siteName = publishData.publishUrl;
  343.  
  344.   var siteCount = {value:0};
  345.   var siteNamePrefs;
  346.   try {
  347.     siteNamePrefs = publishBranch.getChildList("site_name.", siteCount);
  348.   } catch (e) {}
  349.  
  350.   if (!siteNamePrefs || siteCount.value == 0)
  351.   {
  352.     // We currently have no site prefs, so create them
  353.     var siteData = [publishData];
  354.     return SavePublishSiteDataToPrefs(siteData, publishData.siteName);
  355.   }
  356.  
  357.   // Find site number of existing site or fall through at next available one
  358.   // (Number is arbitrary; needed to construct unique "site_name.x" pref string)
  359.   var i;
  360.   for (i = 0; i < siteCount.value; i++)
  361.   {
  362.     var siteName = GetPublishStringPref(publishBranch, "site_name."+i);
  363.     if (siteName == publishData.siteName)
  364.     {
  365.       // Delete prefs for an existing site
  366.       try {
  367.         publishBranch.deleteBranch("site_data." + siteName + ".");
  368.       } catch (e) {}
  369.       break;
  370.     }
  371.   }
  372.  
  373.  
  374.   var ret = SavePublishData_Internal(publishBranch, publishData, i);
  375.   if (ret)
  376.   {
  377.     SavePrefFile();
  378.     // Clear signal to save these data
  379.     if ("notInSiteData" in publishData && publishData.notInSiteData)
  380.       publishData.notInSiteData = false;
  381.   }
  382.   return ret;
  383. }
  384.  
  385. // Save data at a particular site number
  386. function SavePublishData_Internal(publishPrefsBranch, publishData, siteIndex)
  387. {
  388.   if (!publishPrefsBranch || !publishData)
  389.     return false;
  390.  
  391.   SetPublishStringPref(publishPrefsBranch, "site_name."+siteIndex, publishData.siteName);
  392.  
  393.   FixupUsernamePasswordInPublishData(publishData);
  394.  
  395.   var prefPrefix = "site_data." + publishData.siteName + "."
  396.  
  397.   SetPublishStringPref(publishPrefsBranch, prefPrefix+"url", publishData.publishUrl);
  398.   SetPublishStringPref(publishPrefsBranch, prefPrefix+"browse_url", publishData.browseUrl);
  399.   SetPublishStringPref(publishPrefsBranch, prefPrefix+"username", publishData.username);
  400.   
  401.   try {
  402.     publishPrefsBranch.setBoolPref(prefPrefix+"save_password", publishData.savePassword);
  403.     publishPrefsBranch.setBoolPref(prefPrefix+"publish_other_files", publishData.publishOtherFiles);
  404.   } catch (e) {}
  405.  
  406.   // Save password using PasswordManager 
  407.   // (If publishData.savePassword = false, this clears existing password)
  408.   SavePassword(publishData);
  409.  
  410.   SetPublishStringPref(publishPrefsBranch, prefPrefix+"doc_dir", 
  411.                        FormatDirForPublishing(publishData.docDir));
  412.  
  413.   if (publishData.publishOtherFiles && publishData.otherDir)
  414.     SetPublishStringPref(publishPrefsBranch, prefPrefix+"other_dir",
  415.                          FormatDirForPublishing(publishData.otherDir));
  416.  
  417.   if ("saveDirs" in publishData && publishData.saveDirs)
  418.   {
  419.     if (publishData.docDir)
  420.       AppendNewDirToList(publishData, publishData.docDir);
  421.  
  422.     if (publishData.publishOtherFiles && publishData.otherDir 
  423.         && publishData.otherDir != publishData.docDir)
  424.       AppendNewDirToList(publishData, publishData.otherDir);
  425.   }
  426.  
  427.   // Save array of subdirectories with site
  428.   if (publishData.dirList.length)
  429.   {
  430.     publishData.dirList.sort();
  431.     var dirIndex = 0;
  432.     for (var j = 0; j < publishData.dirList.length; j++)
  433.     {
  434.       var dir = publishData.dirList[j];
  435.  
  436.       // Don't store the root dir
  437.       if (dir && dir != "/")
  438.       {
  439.         SetPublishStringPref(publishPrefsBranch, prefPrefix + "dir." + dirIndex, dir);
  440.         dirIndex++;
  441.       }
  442.     }
  443.   }
  444.  
  445.   return true;
  446. }
  447.  
  448. function AppendNewDirToList(publishData, newDir)
  449. {
  450.   newDir = FormatDirForPublishing(newDir);
  451.   if (!publishData || !newDir)
  452.     return;
  453.  
  454.   if (!publishData.dirList)
  455.   {
  456.     publishData.dirList = [newDir];
  457.     return;
  458.   }
  459.  
  460.   // Check if already in the list
  461.   for (var i = 0; i < publishData.dirList.length; i++)
  462.   {
  463.     // Don't add if already in the list
  464.     if (newDir == publishData.dirList[i])
  465.       return;
  466.   }
  467.   // Add to end of list
  468.   publishData.dirList[publishData.dirList.length] = newDir;
  469. }
  470.  
  471. function RemovePublishSubdirectoryFromPrefs(publishData, removeDir)
  472. {
  473.   removeDir = FormatDirForPublishing(removeDir);
  474.   if (!publishData || !publishData.siteName || !removeDir)
  475.     return false;
  476.  
  477.   var publishBranch = GetPublishPrefsBranch();
  478.   if (!publishBranch)
  479.     return false;
  480.  
  481.   var prefPrefix = "site_data." + publishData.siteName + ".";
  482.  
  483.   // Remove dir from the default dir prefs
  484.   if (publishData.docDir == removeDir)
  485.   {
  486.     publishData.docDir = "";
  487.     SetPublishStringPref(publishBranch, prefPrefix+"doc_dir", "");
  488.   }
  489.  
  490.   if (publishData.otherDir == removeDir)
  491.   {
  492.     publishData.otherDir = "";
  493.     SetPublishStringPref(publishBranch, prefPrefix+"other_dir", "");
  494.   }
  495.  
  496.   prefPrefix += "dir.";
  497.  
  498.   // Delete entire subdir list
  499.   try {
  500.     publishBranch.deleteBranch(prefPrefix);
  501.   } catch (e) {}
  502.  
  503.   // Rebuild prefs, skipping over site to remove
  504.   if (publishData.dirList.length)
  505.   {
  506.     var dirIndex = 0;
  507.     var docDirInList = false;
  508.     var otherDirInList = false;
  509.     for (var i = 0; i < publishData.dirList.length; i++)
  510.     {
  511.       var dir = publishData.dirList[i];
  512.       if (dir == removeDir)
  513.       {
  514.         // Remove item from the dirList array
  515.         publishData.dirList.splice(i, 1);
  516.         --i;
  517.       }
  518.       else if (dir && dir != "/") // skip empty or root dir
  519.       {
  520.         // Save to prefs
  521.         SetPublishStringPref(publishBranch, prefPrefix + dirIndex, dir);
  522.         dirIndex++;
  523.       }
  524.     }
  525.   }
  526.   SavePrefFile();
  527.   return true;
  528. }
  529.  
  530. function SetDefaultSiteName(name)
  531. {
  532.   if (name)
  533.   {
  534.     var publishBranch = GetPublishPrefsBranch();
  535.     if (publishBranch)
  536.       SetPublishStringPref(publishBranch, "default_site", name);
  537.  
  538.     SavePrefFile();
  539.   }
  540. }
  541.  
  542. function SavePrefFile()
  543. {
  544.   try {
  545.     if (gPrefsService)
  546.       gPrefsService.savePrefFile(null);
  547.   }
  548.   catch (e) {}
  549. }
  550.  
  551. /***************** Helper / utility methods ********************/
  552.  
  553. function GetPublishPrefsBranch()
  554. {
  555.   var prefsService = GetPrefsService();
  556.   if (!prefsService)
  557.     return null;
  558.  
  559.   return prefsService.getBranch("editor.publish.");
  560. }
  561.  
  562. function GetSiteNameList(doSort, defaultFirst)
  563. {
  564.   var publishBranch = GetPublishPrefsBranch();
  565.   if (!publishBranch)
  566.     return null;
  567.  
  568.   var siteCountObj = {value:0};
  569.   var siteNamePrefs;
  570.   try {
  571.     siteNamePrefs = publishBranch.getChildList("site_name.", siteCountObj);
  572.   } catch (e) {}
  573.  
  574.   if (!siteNamePrefs || siteCountObj.value == 0)
  575.     return null;
  576.  
  577.   // Array of site names
  578.   var siteNameList = [];
  579.   var index = 0;
  580.   var defaultName = "";
  581.   if (defaultFirst)
  582.   {
  583.     defaultName = GetPublishStringPref(publishBranch, "default_site");
  584.     // This always sorts to top -- replace with real string below
  585.     siteNameList[0] = "";
  586.     index++;
  587.   }
  588.  
  589.   for (var i = 0; i < siteCountObj.value; i++)
  590.   {
  591.     var siteName = GetPublishStringPref(publishBranch, siteNamePrefs[i]);
  592.     // Skip if siteName pref is empty or is default name
  593.     if (siteName && siteName != defaultName)
  594.     {
  595.       siteNameList[index] = siteName;
  596.       index++;
  597.     }
  598.   }
  599.  
  600.   if (siteNameList.length && doSort)
  601.     siteNameList.sort();
  602.  
  603.   if (defaultName)
  604.   {
  605.     siteNameList[0] = defaultName;
  606.     index++;
  607.   }
  608.  
  609.   return siteNameList.length? siteNameList : null;
  610. }
  611.  
  612. function PublishSiteNameExists(name, publishSiteData, skipSiteIndex)
  613. {
  614.   if (!name)
  615.     return false;
  616.  
  617.   if (!publishSiteData)
  618.   {
  619.     publishSiteData = GetPublishSiteData();
  620.     skipSiteIndex = -1;
  621.   }
  622.  
  623.   if (!publishSiteData)
  624.     return false;
  625.  
  626.   // Array of site names - sorted, but don't put default name first
  627.   for (var i = 0; i < publishSiteData.length; i++)
  628.   {
  629.     if (i != skipSiteIndex && name == publishSiteData[i].siteName)
  630.       return true;
  631.   }
  632.   return false;
  633. }
  634.  
  635. // Find index of a site record in supplied publish site database
  636. // docUrl: Document URL with or without filename
  637. //         (Must end in "/" if no filename)
  638. // dirObj.value =  the directory of the document URL 
  639. //      relative to the base publishing URL, using "" if none
  640. //
  641. // XXX: Currently finds the site with the longest-matching url;
  642. //      should we look for the shortest instead? Or match just the host portion?
  643. function FindSiteIndexAndDocDir(publishSiteData, docUrl, dirObj)
  644. {
  645.   if (dirObj)
  646.     dirObj.value = "";
  647.  
  648.   if (!publishSiteData || !docUrl || GetScheme(docUrl) == "file")
  649.     return -1;
  650.  
  651.   var siteIndex = -1;
  652.   var siteUrlLen = 0;
  653.   
  654.   for (var i = 0; i < publishSiteData.length; i++)
  655.   {
  656.     // Site publish or browse url needs to be contained in document URL,
  657.     //  but that may also have a directory after the site base URL
  658.     //  So we must examine all records to find the site URL that best
  659.     //    matches the document URL: the longest-matching substring (XXX is this right?)
  660.     var lenObj = {value:0};
  661.     var tempData = publishSiteData[i];
  662.     
  663.     // Check if this site matches docUrl (returns length of match if found)
  664.     var len = FillInMatchingPublishData(tempData, docUrl);
  665.     if (len > siteUrlLen)
  666.     {
  667.       siteIndex = i;
  668.       siteUrlLen = len;
  669.       if (dirObj)
  670.         dirObj.value = tempData.docDir;
  671.  
  672.       // Continue to find the site with longest-matching publishUrl
  673.     }
  674.   }
  675.   return siteIndex;
  676. }
  677.  
  678. // Look for a matching publish url within the document url
  679. // (We need to look at both "publishUrl" and "browseUrl" in case we are editing
  680. //  an http: document but using ftp: to publish.)
  681. // If match is found:
  682. //    Fill in the filename and subirectory based on the docUrl and 
  683. //    return the length of the docUrl with username+password stripped out
  684. function FillInMatchingPublishData(publishData, docUrl)
  685. {
  686.   if (!publishData || !docUrl)
  687.     return 0;
  688.  
  689.   // Separate docUrl into the base url and filename
  690.   var lastSlash = docUrl.lastIndexOf("\/");
  691.   var baseUrl = docUrl.slice(0, lastSlash+1);
  692.   var filename = docUrl.slice(lastSlash+1);
  693.     
  694.   // Strip username+password from docUrl because these
  695.   //  are stored separately in publishData, never embedded in the publishUrl
  696.   // If both docUrl and publishData contain usernames,
  697.   //   we must match that as well as the url
  698.   var username = {value:""};
  699.   baseUrl = StripUsernamePassword(baseUrl, username); 
  700.   username = username.value;
  701.  
  702.   var matchedLength = 0;
  703.   var pubUrlFound = baseUrl.indexOf(publishData.publishUrl) == 0;
  704.   var browseUrlFound = baseUrl.indexOf(publishData.browseUrl) == 0;
  705.  
  706.   if ((pubUrlFound || browseUrlFound) 
  707.       && (!username || !publishData.username || username == publishData.username))
  708.   {
  709.     // We found a match
  710.     matchedLength = pubUrlFound ? publishData.publishUrl.length 
  711.                             : publishData.browseUrl.length;
  712.  
  713.     publishData.filename = filename;
  714.  
  715.     // Subdirectory within the site is whats left in baseUrl after the matched portion
  716.     publishData.docDir = FormatDirForPublishing(baseUrl.slice(matchedLength));
  717.   }
  718.   return matchedLength;
  719. }
  720.  
  721. // Prefs that don't exist will through an exception,
  722. //  so just return an empty string
  723. function GetPublishStringPref(prefBranch, name)
  724. {
  725.   if (prefBranch && name)
  726.   {
  727.     try {
  728.       return prefBranch.getComplexValue(name, Components.interfaces.nsISupportsWString).data;
  729.     } catch (e) {}
  730.   }
  731.   return "";
  732. }
  733.  
  734. function SetPublishStringPref(prefBranch, name, value)
  735. {
  736.   if (prefBranch && name)
  737.   {
  738.     try {
  739.         var str = Components.classes["@mozilla.org/supports-wstring;1"]
  740.                             .createInstance(Components.interfaces.nsISupportsWString);
  741.         str.data = value;
  742.         prefBranch.setComplexValue(name, Components.interfaces.nsISupportsWString, str);
  743.     } catch (e) {}
  744.   }
  745. }
  746.  
  747. // Assure that a publishing URL ends in "/", "=", "&" or "?"
  748. // Username and password should always be extracted as separate fields
  749. //  and are not allowed to remain embeded in publishing URL
  750. function FormatUrlForPublishing(url)
  751. {
  752.   url = TrimString(StripUsernamePassword(url));
  753.   if (url)
  754.   {
  755.     var lastChar = url.charAt(url.length-1);
  756.     if (lastChar != "/" && lastChar != "=" && lastChar != "&" && lastChar  != "?")
  757.       return (url + "/");
  758.   }
  759.   return url;
  760. }
  761.  
  762. // Username and password present in publish url are
  763. //  extracted into the separate "username" and "password" fields 
  764. //  of the publishData object
  765. // Returns true if we did change the publishData
  766. function FixupUsernamePasswordInPublishData(publishData)
  767. {
  768.   var ret = false;
  769.   if (publishData && publishData.publishUrl)
  770.   {
  771.     var userObj = {value:""};
  772.     var passObj = {value:""};
  773.     publishData.publishUrl = FormatUrlForPublishing(StripUsernamePassword(publishData.publishUrl, userObj, passObj));
  774.     if (userObj.value)
  775.     {
  776.       publishData.username = userObj.value;
  777.       ret = true;
  778.     }
  779.     if (passObj.value)
  780.     {
  781.       publishData.password = passObj.value;
  782.       ret = true;
  783.     }
  784.     // While we're at it, be sure browse URL is proper format
  785.     publishData.browseUrl = FormatUrlForPublishing(publishData.browseUrl);
  786.   }
  787.   return ret;
  788. }
  789.  
  790. // Assure that a publishing directory ends with "/" and does not begin with "/"
  791. // Input dir is assumed to be a subdirectory string, not a full URL or pathname
  792. function FormatDirForPublishing(dir)
  793. {
  794.   dir = TrimString(dir);
  795.  
  796.   // The "//" case is an expected "typo" filter
  797.   //  that simplifies code below!
  798.   if (!dir || dir == "/" || dir == "//")
  799.     return "";
  800.  
  801.   // Remove leading "/"
  802.   if (dir.charAt(0) == "/")
  803.     dir = dir.slice(1);
  804.  
  805.   // Append "/" at the end if necessary
  806.   var dirLen = dir.length;
  807.   var lastChar = dir.charAt(dirLen-1);
  808.   if (dirLen > 1 && lastChar != "/" && lastChar != "=" && lastChar != "&" && lastChar  != "?")
  809.     return (dir + "/");
  810.  
  811.   return dir;
  812. }
  813.  
  814.  
  815. var gPasswordManager;
  816. function GetPasswordManager()
  817. {
  818.   if (!gPasswordManager)
  819.   {
  820.     var passwordManager = Components.classes["@mozilla.org/passwordmanager;1"].createInstance();
  821.     if (passwordManager)
  822.       gPasswordManager = passwordManager.QueryInterface(Components.interfaces.nsIPasswordManager);
  823.   }
  824.   return gPasswordManager;
  825. }
  826.  
  827. var gPasswordManagerInternal;
  828. function GetPasswordManagerInternal()
  829. {
  830.   if (!gPasswordManagerInternal)
  831.   {
  832.     try {
  833.       gPasswordManagerInternal =
  834.         Components.classes["@mozilla.org/passwordmanager;1"].createInstance(
  835.           Components.interfaces.nsIPasswordManagerInternal);
  836.     } catch (e) {
  837.     }
  838.   }
  839.   return gPasswordManagerInternal;
  840. }
  841.  
  842. function GetSavedPassword(publishData)
  843. {
  844.   if (!publishData)
  845.     return "";
  846.   var passwordManagerInternal = GetPasswordManagerInternal();
  847.   if (!passwordManagerInternal)
  848.     return "";
  849.  
  850.   var host = {value:""};
  851.   var user =  {value:""};
  852.   var password = {value:""}; 
  853.   var url = GetUrlForPasswordManager(publishData);
  854.   
  855.   try {
  856.     passwordManagerInternal.findPasswordEntry
  857.       (url, publishData.username, "", host, user, password);
  858.     return password.value;
  859.   } catch (e) {}
  860.  
  861.   return "";
  862. }
  863.  
  864. function SavePassword(publishData)
  865. {
  866.   if (!publishData || !publishData.publishUrl || !publishData.username)
  867.     return false;
  868.  
  869.   var passwordManager = GetPasswordManager();
  870.   if (passwordManager)
  871.   {
  872.     var url = GetUrlForPasswordManager(publishData);
  873.  
  874.     // Remove existing entry
  875.     // (Note: there is no method to update a password for an existing entry)
  876.     try {
  877.       passwordManager.removeUser(url, publishData.username);
  878.     } catch (e) {}
  879.  
  880.     // If SavePassword is true, add new password
  881.     if (publishData.savePassword)
  882.     {
  883.       try {
  884.         passwordManager.addUser(url, publishData.username, publishData.password);
  885.       } catch (e) {}
  886.     }
  887.     return true;
  888.   }
  889.   return false;
  890. }
  891.  
  892. function GetUrlForPasswordManager(publishData)
  893. {
  894.   if (!publishData || !publishData.publishUrl)
  895.     return false;
  896.  
  897.   var url;
  898.  
  899.   // For FTP, we must embed the username into the url for a site address
  900.   // XXX Maybe we should we do this for HTTP as well???
  901.   if (publishData.username && GetScheme(publishData.publishUrl) == "ftp")
  902.     url = InsertUsernameIntoUrl(publishData.publishUrl, publishData.username);
  903.   else
  904.     url = publishData.publishUrl;
  905.  
  906.   // Strip off terminal "/"
  907.   var len = url.length;
  908.   if (len && url.charAt(len-1) == "\/")
  909.     url = url.slice(0, len-1);
  910.   
  911.   return url;
  912. }
  913.